package core.process;

import core.utils.EPara;
import core.utils.Utils;
import core.process.pack.IndelPack;
import core.process.pack.IndelData;
import core.rb.PB;
import core.rb.r.PR;
import gui.processor.Processor;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

/*Author: John Archer, Contact: john.archer.jpa@gmail.com*/
public class Indel{
    protected PB pBlock;
    private Processor gp;
    public Indel(PB pBlock, Processor gp){this.pBlock = pBlock;this.gp = gp;}
    public IndelData getIndels() throws Exception{
        int size = (int)((pBlock.getSize() / EPara.THREADS));
        int i = 0;
        ArrayList <PB> packs = new ArrayList();
        ArrayList <PR> pack;
        for(int x = 0; x<EPara.THREADS; x++){
            pack = new ArrayList();
            for(int y = 0; y<size; y++){pack.add(pBlock.getRead(i++));}
            packs.add(new PB(pBlock.getRef(), pack));
        }
        PB fPack = packs.get(0);
        for(int x=i; x<pBlock.getSize(); x++){fPack.add(pBlock.getRead(i++));}
        IndelPack [] ip = new IndelPack[packs.size()];
        CountDownLatch cdl = new CountDownLatch(packs.size());
        for (int x = 0; x < packs.size(); x++){ip[x] = new IndelPack(gp, cdl, packs.get(x));}
        cdl.await();
        ArrayList <IndelData> combined = new ArrayList();
        for (int x = 0; x < ip.length; x++){combined.add(ip[x].getPOut());}
        int[][] combDels = new int[EPara.MAXINDEL][pBlock.getRef().getDNA().length()];
        int[][] combIns = new int[EPara.MAXINDEL][pBlock.getRef().getDNA().length()];
        for (int x = 0; x < combined.size(); x++) {
            Utils.add(combined.get(x).getDels(), combDels);
            Utils.add(combined.get(x).getIns(), combIns);
        }
        return new IndelData(combIns, combDels);
    }
}